package c

import (
	"errors"
	"fmt"
	"strconv"

	"github.com/bytedance/sonic"
	"go.uber.org/zap"

	"github.com/flipped-aurora/gin-vue-admin/server/global"
	"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
	request_model "github.com/flipped-aurora/gin-vue-admin/server/model/content/request"
	"github.com/flipped-aurora/gin-vue-admin/server/service/c"
	"github.com/flipped-aurora/gin-vue-admin/server/service/system"
	"github.com/flipped-aurora/gin-vue-admin/server/utils"
	"github.com/gin-gonic/gin"
)

// ContentApi 内容相关接口
type ContentApi struct{}

// CreateContent 创建内容
// @Tags Content
// @Summary 创建内容
// @Produce  application/json
// @Param data body request_model.CreateContentRequest true "创建内容"
// @Success 200 {object} response.Response{data=response_model.ContentResponse,msg=string}
// @Router /c/content/createContent [post]
func (con *ContentApi) CreateContent(ctx *gin.Context) {
	var request request_model.CreateContentRequest
	var errBind = ctx.ShouldBindJSON(&request)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败: "+errBind.Error(), ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userId := utils.GetUserID(ctx)

	// 这里可以增加用户权限、能否发帖校验
	// 1. 检查用户是否已完成专业认证,未认证无法发帖
	isAuth, err := system.UserServiceApp.CheckUserMajorAuthStatus(userId)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
	}

	if !isAuth {
		errReq := errors.New("创建内容失败: 您需要先完成专业认证")
		response.FailWithMessage(errReq.Error(), ctx)
		return // 添加 return 语句
	}

	// 调用服务层创建内容
	resp, errReq := c.ContentServiceApp.CreateContent(request, userId)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "创建成功", ctx)
}

// GetContentByID 根据 ID 查询内容
// @Tags Content
// @Summary 根据 ID 查询内容
// @Produce  application/json
// @Param id query int true "内容ID"
// @Success 200 {object} response.Response{data=response_model.ContentResponse,msg=string}
// @Router /c/content/getContent [get]
func (con *ContentApi) GetContentByID(ctx *gin.Context) {
	idStr := ctx.Query("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: id 必须是数字", ctx)
		return
	}

	var request = request_model.GetContentRequest{ID: id}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层查询内容
	resp, errReq := c.ContentServiceApp.GetContentByID(request, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}

func (con *ContentApi) ListLikesContent(ctx *gin.Context) {
	var req request_model.ListLikesRequest
	var errBind = ctx.ShouldBindQuery(&req)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败:"+errBind.Error(), ctx)
		return
	}
	// 从JWT中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层
	resp, errReq := c.ContentServiceApp.ListLikeContents(req, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}

func (con *ContentApi) ListMarkContent(ctx *gin.Context) {
	var req request_model.ListMarksRequest
	var errBind = ctx.ShouldBindQuery(&req)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败:"+errBind.Error(), ctx)
		return
	}
	// 从JWT中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层
	resp, errReq := c.ContentServiceApp.ListMarkContents(req, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}

// UpdateContent 更新内容（仅发布者或管理员可操作）
// @Tags Content
// @Summary 更新内容
// @Produce  application/json
// @Param data body request_model.UpdateContentRequest true "更新内容"
// @Success 200 {object} response.Response{data=response_model.ContentResponse,msg=string}
// @Router /c/content/updateContent [put]
func (con *ContentApi) UpdateContent(ctx *gin.Context) {
	var request request_model.UpdateContentRequest
	var errBind = ctx.ShouldBindJSON(&request)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败: "+errBind.Error(), ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层更新内容
	resp, errReq := c.ContentServiceApp.UpdateContent(request, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "更新成功", ctx)
}

// DeleteContent 逻辑删除内容（Status=1）
// @Tags Content
// @Summary 删除内容
// @Produce  application/json
// @Param data body request_model.DeleteContentRequest true "删除内容"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/deleteContent [delete]
func (con *ContentApi) DeleteContent(ctx *gin.Context) {
	var request request_model.DeleteContentRequest
	var errBind = ctx.ShouldBindJSON(&request)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败: "+errBind.Error(), ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层删除内容
	_, errReq := c.ContentServiceApp.DeleteContent(request, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithMessage("删除成功", ctx)
}

// LikeContent 点赞内容
// @Tags Content
// @Summary 点赞内容
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/likeContent [post]
func (con *ContentApi) LikeContent(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	logId := utils.GetLogID(ctx)

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 这里需要写一个统一的互动校验，对于动态，只有本专业类的用户可以操作
	err = c.ContentServiceApp.ValidateContentInteraction(contentID, userID)
	if err != nil {
		global.GVA_LOG.Warn("点赞操作失败！权限校验不通过！", zap.Error(err), zap.Int64("contentID", contentID), zap.Int64("userID", int64(userID)), zap.String("logID", logId))
		response.FailWithMessage("点赞失败！校验不通过！", ctx)
		return
	}

	// 调用服务层点赞内容
	err = c.ContentServiceApp.LikeContent(ctx, contentID, userID)
	if err != nil {
		global.GVA_LOG.Warn("点赞操作失败！", zap.Error(err), zap.Int64("contentID", contentID), zap.Int64("userID", int64(userID)), zap.String("logID", logId))
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithMessage("操作成功", ctx)
}

// DislikeContent 点踩内容
// @Tags Content
// @Summary 点踩内容
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/dislikeContent [post]
func (con *ContentApi) DislikeContent(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	err = c.ContentServiceApp.ValidateContentInteraction(contentID, userID)
	if err != nil {
		response.FailWithMessage("非本专业用户无法操作", ctx)
		return
	}

	// 调用服务层点踩内容
	err = c.ContentServiceApp.DislikeContent(contentID, userID)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithMessage("操作成功", ctx)
}

// MarkContent 收藏内容
// @Tags Content
// @Summary 收藏内容
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/markContent [post]
func (con *ContentApi) MarkContent(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	err = c.ContentServiceApp.ValidateContentInteraction(contentID, userID)
	if err != nil {
		response.FailWithMessage("非本专业用户无法操作", ctx)
		return
	}

	// 调用服务层收藏内容
	err = c.ContentServiceApp.MarkContent(contentID, userID)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithMessage("操作成功", ctx)
}

// ShareContent 分享内容
// @Tags Content
// @Summary 分享内容
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/shareContent [post]
func (con *ContentApi) ShareContent(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层分享内容
	err = c.ContentServiceApp.ShareContent(contentID, userID)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithMessage("操作成功", ctx)
}

// ViewContent 浏览内容
// @Tags Content
// @Summary 浏览内容
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/viewContent [post]
func (con *ContentApi) ViewContent(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层浏览内容
	err = c.ContentServiceApp.ViewContent(contentID, userID)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithMessage("操作成功", ctx)
}

// ProfRatingContent 对内容进行专业评分
// @Tags Content
// @Summary 对内容进行专业评分
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Param score query int true "评分 (1-10分)"
// @Success 200 {object} response.Response{msg=string}
// @Router /c/content/profRatingContent [post]
func (con *ContentApi) ProfRatingContent(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	// 获取评分
	scoreStr := ctx.Query("score")
	score, err := strconv.Atoi(scoreStr)
	if err != nil {
		response.FailWithMessage("参数错误: score 必须是数字", ctx)
		return
	}

	// 验证评分范围 (1-10分)
	if score < 1 || score > 10 {
		response.FailWithMessage("评分必须在1-10分之间", ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	err = c.ContentServiceApp.ValidateContentInteraction(contentID, userID)
	if err != nil {
		response.FailWithMessage("非本专业用户无法操作", ctx)
		return
	}

	// 调用服务层进行专业评分
	err = c.ContentServiceApp.ProfRatingContent(contentID, userID, score)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithMessage("评分成功", ctx)
}

// GetContentProfRating 获取内容的专业评分信息
// @Tags Content
// @Summary 获取内容的专业评分信息
// @Produce  application/json
// @Param contentId query int true "内容ID"
// @Success 200 {object} response.Response{data=response_model.ProfRatingResponse,msg=string}
// @Router /c/content/getContentProfRating [get]
func (con *ContentApi) GetContentProfRating(ctx *gin.Context) {
	// 获取内容ID
	contentIdStr := ctx.Query("contentId")
	contentID, err := strconv.ParseInt(contentIdStr, 10, 64)
	if err != nil {
		response.FailWithMessage("参数错误: contentId 必须是数字", ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层获取专业评分信息
	resp, err := c.ContentServiceApp.GetContentProfRating(contentID, userID)
	if err != nil {
		response.FailWithMessage(err.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}

// GetUserRelatedContent 获取用户相关内容
// @Tags Content
// @Summary 获取用户相关内容
// @Produce  application/json
// @Param page query int true "页码"
// @Param pageSize query int true "每页数量"
// @Param contentType query int false "内容类型（0-全部，1-动态，2-提问，3-回答）"
// @Param includeType query string false "包含类型（all-全部，interacted-互动内容，published-发布内容）"
// @Param actionTypes query []string false "互动类型列表（like,dislike,mark,share,prof_rating）"
// @Success 200 {object} response.Response{data=response_model.PageResult,msg=string}
// @Router /c/content/getUserRelatedContent [get]
func (con *ContentApi) GetUserRelatedContent(ctx *gin.Context) {
	var request = request_model.UserRelatedContentRequest{}
	var errBind = ctx.ShouldBindQuery(&request)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败: "+errBind.Error(), ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层查询用户相关内容
	resp, errReq := c.ContentServiceApp.GetUserRelatedContent(request, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}

// GetContentListByCommunity 根据社区类型自动选择查询逻辑
// @Tags Content
// @Summary 根据社区类型自动选择查询逻辑
// @Produce  application/json
// @Param communityId query int true "社区ID"
// @Param type query int false "内容类型"
// @Param page query int true "页码"
// @Param pageSize query int true "每页数量"
// @Success 200 {object} response.Response{data=response_model.PageResult,msg=string}
// @Router /c/content/getContentListByCommunity [get]
func (con *ContentApi) GetContentListByCommunity(ctx *gin.Context) {
	var request request_model.ListContentRequest
	var errBind = ctx.ShouldBindQuery(&request)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败: "+errBind.Error(), ctx)
		return
	}

	// 从 JWT 中获取用户信息
	userID := utils.GetUserID(ctx)

	// 调用服务层新方法
	resp, errReq := c.ContentServiceApp.GetContentListByCommunity(request, userID)
	if errReq != nil {
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}

// GetUserContentActions 查询用户内容操作记录
// @Tags Content
// @Summary 查询用户内容操作记录
// @Produce  application/json
// @Param page query int true "页码"
// @Param pageSize query int true "每页数量"
// @Param content_type query int true "内容类型（1-动态，2-提问，3-回答）"
// @Param action_type query int true "操作类型（-1-发布，-2-评价，1-点赞，3-收藏）"
// @Param user_id query int false "用户id; 当用户id不传时，默认查询当前登陆用户的内容操作记录"
// @Success 200 {object} response.Response{data=response_model.ContentUserActionResponse,msg=string}
// @Router /c/content/getUserContentActions [get]
func (con *ContentApi) GetUserContentActions(ctx *gin.Context) {
	var request request_model.ContentUserActionRequest
	var errBind = ctx.ShouldBindQuery(&request)
	if errBind != nil {
		response.FailWithMessage("参数绑定失败: "+errBind.Error(), ctx)
		return
	}

	fmt.Println(sonic.MarshalString(request))

	// 从 JWT 中获取当前登录用户信息
	currentUserID := utils.GetUserID(ctx)

	logID := utils.GetLogID(ctx)

	// 调用服务层查询用户内容操作记录
	resp, errReq := c.ContentServiceApp.GetUserContentActions(ctx, request, currentUserID)
	if errReq != nil {
		global.GVA_LOG.Warn("查询用户内容操作记录失败！", zap.Error(errReq), zap.Int64("userID", int64(currentUserID)), zap.String("logID", logID), zap.Int("contentType", int(request.ContentType)), zap.Int("actionType", int(request.ActionType)))
		response.FailWithMessage(errReq.Error(), ctx)
		return
	}

	response.OkWithDetailed(resp, "查询成功", ctx)
}
